from PyQt4.QtCore import QDir
from PyQt4.QtCore import QDirIterator
from PyQt4.QtCore import QString
from PyQt4.QtCore import QVariant
from PyQt4.QtCore import Qt
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QAbstractItemView
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QCursor
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QListView
from PyQt4.QtGui import QMenu
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import qApp
from PyQt4.QtSql import QSqlQueryModel


class LibraryRoom(QWidget):
    def __init__(self, phonik):
        #parent constructor
        QWidget.__init__(self)

        self.phonik = phonik
        self.mediaManager = phonik.mediaManager
        self.query = phonik.query
        self.playList = phonik.playList

        #setup ui
        self.setupUi()

        #read library
        self.loadLibrary()

        #signals
        self.signals()

        self.selectedGenre = ''
        self.selectedArtist = ''
        self.selectedAlbum = ''


    def setupUi(self):

        #init gui
        self.horizontalLayout = QHBoxLayout(self)
        self.horizontalLayout.setMargin(0)

        #genres
        self.genresView = QListView()
        self.genresView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.genresView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.genresModel = QSqlQueryModel()
        self.genresView.setModel(self.genresModel)
        self.horizontalLayout.addWidget(self.genresView)

        #artists
        self.artistsView = QListView()
        self.artistsView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.artistsView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.artistsModel = QSqlQueryModel()
        self.artistsView.setModel(self.artistsModel)
        self.horizontalLayout.addWidget(self.artistsView)

        #albums
        self.albumsView = QListView()
        self.albumsView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.albumsView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.albumsModel = QSqlQueryModel()
        self.albumsView.setModel(self.albumsModel)
        self.horizontalLayout.addWidget(self.albumsView)


    def loadLibrary(self):
        self.selectedGenre = self.selectedArtist = self.selectedAlbum = ''
        self.genresModel.setQuery('select genre from genres order by genre')
        self.artistsModel.setQuery('select distinct artist from artists order by artist')
        self.albumsModel.setQuery('select distinct album from albums order by album')
        


    def selectGenre(self, genre):

        self.selectedGenre = genre
        self.loadLibrary()
        self.genresView.setCurrentIndex(self.genresModel.match (self.genresModel.index(0, 0), Qt.DisplayRole, QVariant(genre), 1, Qt.MatchExactly)[0])


    def genresListViewClicked(self):

        selection = self.genresView.selectedIndexes()
        if selection and qApp.mouseButtons() != Qt.RightButton:
            self.selectedGenre = '" or genre="'.join([str(k.data().toString().toUtf8()) for k in selection])

            self.artistsModel.setQuery('select distinct artist from artists where genre="' + self.selectedGenre + '" order by artist')
            self.albumsModel.setQuery('select distinct album from albums where genre="' + self.selectedGenre + '" order by album')
            self.selectPlaylist('select * from titles where genre="' + self.selectedGenre + '" order by artist,album,track,file')
            self.playList.setSortIndicator(2)
            self.selectedArtist = ''


    def selectArtist(self, artist):

        self.selectedArtist = artist
        self.loadLibrary()
        self.artistsView.setCurrentIndex(self.artistsModel.match (self.artistsModel.index(0, 0), Qt.DisplayRole, QVariant(artist), 1, Qt.MatchExactly)[0])
        self.selectedGenre = self.selectedAlbum = ''


    def artistsListViewClicked(self):

        selection = self.artistsView.selectedIndexes()
        if selection and qApp.mouseButtons() != Qt.RightButton:
            self.selectedArtist = '" or artist="'.join([str(k.data().toString()) for k in selection])

            playListsql = 'select * from titles where artist="' + self.selectedArtist
            albumsSql = 'select distinct album from albums where artist="' + self.selectedArtist
            if self.selectedGenre  != '':
                self.albumsModel.setQuery(albumsSql + '" and genre="' + self.selectedGenre + '" order by album')
                self.selectPlaylist(playListsql + '" and genre="' + self.selectedGenre + '" order by artist,album,track,file')
            else:
                self.albumsModel.setQuery(albumsSql + '" order by album')
                self.selectPlaylist(playListsql + '" order by artist,album,track,file')
            self.playList.setSortIndicator(3)


    def selectAlbum(self, album):
        self.selectedAlbum = album
        self.loadLibrary()
        self.albumsView.setCurrentIndex(self.albumsModel.match (self.albumsModel.index(0, 0), Qt.DisplayRole, QVariant(album), 1, Qt.MatchExactly)[0])
        self.selectedGenre = self.selectedArtist = ''


    def albumsListViewClicked(self):

        selection = self.albumsView.selectedIndexes()
        if selection and qApp.mouseButtons() != Qt.RightButton:

            self.selectedAlbum = '" or album="'.join([str(k.data().toString()) for k in selection])

            playListsql = 'select * from titles where album="' + self.selectedAlbum
            if self.selectedGenre  == '' and self.selectedArtist  == '':
                self.selectPlaylist(playListsql + '" order by track,file')

            elif self.selectedGenre  != '' and self.selectedArtist  != '':
                self.selectPlaylist(playListsql + '" and artist="' + self.selectedArtist + '" and genre="' + self.selectedGenre + '" order by track,file')

            elif self.selectedGenre  != '':
                self.selectPlaylist(playListsql + '" and genre="' + self.selectedGenre + '" order by track,file')

            elif self.selectedArtist  != '':
                self.selectPlaylist(playListsql + '" and artist="' + self.selectedArtist + '" order by track,file')

            self.playList.setSortIndicator(0)


    def selectFullPath(self, title):

        self.query.exec_('select distinct genre,artist,album from titles where title="' + title + '"')
        self.query.next()
        genre = self.query.value(0).toString()
        artist = self.query.value(1).toString()
        album = self.query.value(2).toString()
        
        self.genresView.setCurrentIndex(self.genresModel.match (self.genresModel.index(0, 0), Qt.DisplayRole, QVariant(genre), 1, Qt.MatchExactly)[0])
        self.artistsView.setCurrentIndex(self.artistsModel.match (self.artistsModel.index(0, 0), Qt.DisplayRole, QVariant(artist), 1, Qt.MatchExactly)[0])
        self.albumsView.setCurrentIndex(self.albumsModel.match (self.albumsModel.index(0, 0), Qt.DisplayRole, QVariant(album), 1, Qt.MatchExactly)[0])


    def doubleClicked(self):
        self.phonik.mediaManager.playFirst()


    def showContextMenu(self, pos):
        actionList = [QAction(self.tr('Delete'), self)]
        result = QMenu().exec_(actionList, QCursor.pos())
        if result:
            if result.text() == self.tr('Delete'):
                values = [index.data().toString() for index in self.phonik.sender().selectedIndexes()]
                for value in values:
                    self.delete(self.phonik.sender(), value)
                self.loadLibrary()


    def delete(self, sender=None, value=None):
        if sender:
            if sender == self.genresView:
                self.query.exec_('delete from genres where genre="' + value + '"')
                self.query.exec_('delete from artists where genre="' + value + '"')
                self.query.exec_('delete from albums where genre="' + value + '"')
                self.query.exec_('delete from titles where genre="' + value + '"')
            elif sender == self.artistsView:
                self.query.exec_('delete from artists where artist="' + value + '"')
                self.query.exec_('delete from albums where artist="' + value + '"')
                self.query.exec_('delete from titles where artist="' + value + '"')
            elif sender == self.albumsView:
                self.query.exec_('delete from albums where album="' + value + '"')
                self.query.exec_('delete from titles where album="' + value + '"')

        else:
            self.query.exec_('delete from genres')
            self.query.exec_('delete from artists')
            self.query.exec_('delete from albums')
            self.query.exec_('delete from titles')
            self.phonik.setValue('library-dirs', '')

        self.cleanLibrary()


    def selectPlaylist(self, query):
        self.playList.clearModel()

        self.query.exec_(query)
        while self.query.next():
            metaData = dict()
            metaData[QString('TRACKNUMBER')] = [self.query.value(0).toString()]
            metaData[QString('TITLE')] = [self.query.value(1).toString()]
            metaData[QString('ARTIST')] = [self.query.value(2).toString()]
            metaData[QString('ALBUM')] = [self.query.value(3).toString()]
            metaData[QString('DATE')] = [self.query.value(4).toString()]
            metaData[QString('TIME')] = [self.query.value(5).toString()]
            metaData[QString('GENRE')] = [self.query.value(6).toString()]
            metaData[QString('URL')] = [self.query.value(7).toString()]
            self.playList.addRow(metaData)


    def cleanLibrary(self):

        #deletes unexisting files
        existingFiles = []
        for dir in self.phonik.getValue('library-dirs').split('//|\\'):
            if not dir.isEmpty():
                it = QDirIterator(QString.fromUtf8(dir), QDir.Files, QDirIterator.Subdirectories)
                while it.hasNext():
                    existingFiles.append(it.next())


        libraryFiles = []

        self.query.exec_('select file from titles')
        while(self.query.next()):
            libraryFiles.append(self.query.value(0).toString())

        for file in libraryFiles:
            if file not in existingFiles:
                self.query.exec_('delete from titles where file ="' + file + '"')


        #deletes unused library folders
        if len(self.phonik.getValue('library-dirs').split('//|\\')) > 1:
            sql = 'delete from titles where'
            for dir in self.phonik.getValue('library-dirs').split('//|\\'):
                if not dir.isEmpty():
                    sql += ' file not like "' + dir + '%" and'
            self.query.exec_(sql[:-3])
        else:
            self.query.exec_('delete from titles')

        #deletes unused genres,artists,albums
        self.query.exec_('delete from genres where genre not in (select genre from titles)')
	self.query.exec_('delete from artists where artist not in (select artist from titles)')
	self.query.exec_('delete from albums where album not in (select album from titles)')
        

    def signals(self):
        self.connect(self.genresView.selectionModel (), SIGNAL('selectionChanged (QItemSelection , QItemSelection)'), self.genresListViewClicked)
        self.connect(self.artistsView.selectionModel (), SIGNAL('selectionChanged (QItemSelection , QItemSelection)'), self.artistsListViewClicked)
        self.connect(self.albumsView.selectionModel (), SIGNAL('selectionChanged (QItemSelection , QItemSelection)'), self.albumsListViewClicked)
        self.connect(self.genresView, SIGNAL('doubleClicked(QModelIndex)'), self.doubleClicked)
        self.connect(self.artistsView, SIGNAL('doubleClicked(QModelIndex)'), self.doubleClicked)
        self.connect(self.albumsView, SIGNAL('doubleClicked(QModelIndex)'), self.doubleClicked)
        self.connect(self.genresView, SIGNAL('customContextMenuRequested(const QPoint &)'), self.showContextMenu)
        self.connect(self.artistsView, SIGNAL('customContextMenuRequested(const QPoint &)'), self.showContextMenu)
        self.connect(self.albumsView, SIGNAL('customContextMenuRequested(const QPoint &)'), self.showContextMenu)
